# -*- coding: utf-8 -*-
"""
-----------------------------------------------------------------
    File Name   : request_util.py
    Description : 请求处理工具
    Author      : DuanGe
    Created On  : 2024/11/19
    Email       : duangeali@aliyun.com
    Version     : 1.0.0
    Copyright   : Copyright (c) 2024 DuanGe
    License     : Apache License 2.0
-----------------------------------------------------------------
"""
import requests
from requests.exceptions import MissingSchema, InvalidURL, URLRequired, ConnectionError, Timeout, TooManyRedirects, \
    HTTPError, SSLError, RequestException

from common.common import error_tip
from common.log import request_logger, add_logs

# 创建一个请求会话实例，用于管理整个会话的所有请求
session = requests.Session()
# 超时时间
max_timeout = 15


def send_request(method: str, url: str, **kwargs: any):
    """
    发送HTTP请求

    :param method: 请求方法
    :param url: 请求的目标URL
    :param kwargs: 其他参数
    :return: 响应对象 / None
    """
    # 默认启用SSL验证
    verify_ssl = kwargs.pop('verify_ssl', True)
    operation = f"{method}请求"
    msg = f"URL: {url}, Params: {kwargs}, Verify: {verify_ssl}"
    try:
        response = session.request(method=method, url=url, verify=verify_ssl, **kwargs)
        response.raise_for_status()
        # 记录日志
        add_logs(request_logger, "INFO", operation, msg)
        return response
    except (MissingSchema, InvalidURL, URLRequired, ConnectionError, Timeout, TooManyRedirects, HTTPError, SSLError,
            RequestException, Exception) as e:
        err_msg = {
            MissingSchema: "URL缺少协议",
            InvalidURL: "无效的URL",
            URLRequired: "请求缺少必要的URL",
            ConnectionError: "网络连接错误",
            Timeout: "请求超时",
            TooManyRedirects: "过多重定向",
            HTTPError: "HTTP请求失败",
            SSLError: "SSL证书验证失败",
            RequestException: "请求异常",
            Exception: "发生未知错误"
        }.get(type(e), "发生未知错误")
        error_tip(f"{operation}失败, {err_msg}")
        # 记录日志
        add_logs(request_logger, "ERROR", operation, msg, err_msg, e)
        custom_response = requests.Response()
        custom_response._content = b'{}'
        return custom_response


def send_get_request(url: str, params: dict = None, headers: dict = None, timeout: float = max_timeout,
                     verify_ssl: bool = True):
    """
    发送GET请求

    :param url: 请求的目标URL
    :param params: 查询参数字典
    :param headers: 请求头字典
    :param timeout: 超时时间
    :param verify_ssl: 是否验证SSL证书
    :return: 响应对象 / None
    """
    return send_request(method='GET', url=url, params=params, headers=headers, timeout=timeout, verify_ssl=verify_ssl)


def send_post_request(url: str, data: dict = None, json: dict = None, headers: dict = None, params: dict = None,
                      timeout: float = max_timeout, verify_ssl: bool = True):
    """
    发送POST请求

    :param url: 请求的目标URL
    :param data: 表单数据字典
    :param json: JSON格式的数据
    :param headers: 请求头字典
    :param params: 查询参数字典
    :param timeout: 超时时间
    :param verify_ssl: 是否验证SSL证书
    :return: 响应对象 / None
    """
    return send_request(method='POST', url=url, data=data, json=json, headers=headers, params=params, timeout=timeout,
                        verify_ssl=verify_ssl)


def send_put_request(url: str, data: dict = None, json: dict = None, headers: dict = None, timeout: float = max_timeout,
                     verify_ssl: bool = True):
    """
    发送PUT请求

    :param url: 请求的目标URL
    :param data: 表单数据字典
    :param json: JSON格式的数据
    :param headers: 请求头字典
    :param timeout: 超时时间
    :param verify_ssl: 是否验证SSL证书
    :return: 响应对象 / None
    """
    return send_request(method='PUT', url=url, data=data, json=json, headers=headers, timeout=timeout,
                        verify_ssl=verify_ssl)


def send_delete_request(url: str, params: dict = None, headers: dict = None, timeout: float = max_timeout,
                        verify_ssl: bool = True):
    """
    发送DELETE请求

    :param url: 请求的目标URL
    :param params: 查询参数字典
    :param headers: 请求头字典
    :param timeout: 超时时间
    :param verify_ssl: 是否验证SSL证书
    :return: 响应对象 / None
    """
    return send_request(method='DELETE', url=url, params=params, headers=headers, timeout=timeout,
                        verify_ssl=verify_ssl)
